/**
 *
 */
package com.ybkj.daijia.server.service.impl;

import com.ybkj.daijia.InfoFeeType;
import com.ybkj.daijia.OrderNumberConfig;
import com.ybkj.daijia.Setting;
import com.ybkj.daijia.serverUtils.SettingUtils;
import com.ybkj.daijia.common.Principal;
import com.ybkj.daijia.common.Result;
import com.ybkj.daijia.config.PassengerApi;
import com.ybkj.daijia.server.OrderRevokeTimerTask;
import com.ybkj.daijia.server.event.model.OrderCancelEvent;
import com.ybkj.daijia.server.mapper.CompanyMapper;
import com.ybkj.daijia.server.mapper.DriverConsumedRecordMapper;
import com.ybkj.daijia.server.mapper.DriverMapper;
import com.ybkj.daijia.server.mapper.DriverPaymentsRecordMapper;
import com.ybkj.daijia.server.mapper.FinancialRecordMapper;
import com.ybkj.daijia.server.mapper.MemberMapper;
import com.ybkj.daijia.server.mapper.OrderGroupMapper;
import com.ybkj.daijia.server.mapper.OrderMapper;
import com.ybkj.daijia.server.mapper.OrderStatusMapper;
import com.ybkj.daijia.server.mc.Passenger;
import com.ybkj.daijia.server.model.Admin;
import com.ybkj.daijia.server.model.Company;
import com.ybkj.daijia.server.model.Driver;
import com.ybkj.daijia.server.model.DriverPaymentsRecord;
import com.ybkj.daijia.server.model.FinancialRecord;
import com.ybkj.daijia.server.model.Order;
import com.ybkj.daijia.server.model.OrderGroup;
import com.ybkj.daijia.server.model.OrderStatus;
import com.ybkj.daijia.server.model.OrderStatus.StatusType;
import com.ybkj.daijia.server.scheduler.ThreadControl;
import com.ybkj.daijia.server.service.BossService;
import com.ybkj.daijia.server.service.ChartYearService;
import java.math.BigDecimal;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Timer;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.event.ApplicationEventMulticaster;
import org.springframework.core.task.TaskExecutor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

/**
 * @author Shine
 *
 */
@Service
public class DefaultBossService implements BossService {

    @Autowired
    private DriverMapper driverMapper;

    @Autowired
    private CompanyMapper companyMapper;

    @Autowired
    private OrderMapper orderMapper;

    @Autowired
    private OrderStatusMapper orderStatusMapper;

    @Autowired
    private DriverConsumedRecordMapper driverConsumedRecordMapper;

    @Autowired
    private MemberMapper memberMapper;

    @Autowired
    private FinancialRecordMapper financialRecordMapper;

    @Autowired
    private OrderGroupMapper orderGroupMapper;

    @Autowired
    private DriverPaymentsRecordMapper driverPaymentsRecordMapper;

    @Autowired
    private ChartYearService chartYearService;

    @Autowired
    private SettingUtils settingUtils;

    @Autowired
    private ApplicationEventMulticaster applicationEventMulticaster;

    @Autowired
    private TaskExecutor taskExecutor;

    @Autowired
    private PassengerApi passengerApi;

    @Override
    public Map<String, Object> indexData(Admin admin) {

        Company company = companyMapper
            .selectByPrimaryKey(admin.getCompanyId()); //admin.getCompany();
        Setting setting = settingUtils.get();

        Map<String, Object> map = new HashMap<String, Object>();
        Calendar nowCalendar = Calendar.getInstance();
        int nowHour = nowCalendar.get(Calendar.HOUR_OF_DAY);
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        //昨日
        calendar.set(Calendar.HOUR_OF_DAY, setting.getWorkBegin());
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        calendar.add(Calendar.DAY_OF_MONTH, -1);
        Date yestodayStart = calendar.getTime();
        calendar.add(Calendar.DAY_OF_MONTH, 1);
        Date yestodayEnd = calendar.getTime();
        if (setting.getWorkBegin() > nowHour) {
            calendar.add(Calendar.DAY_OF_MONTH, -2);
            yestodayStart = calendar.getTime();
            calendar.add(Calendar.DAY_OF_MONTH, 1);
            yestodayEnd = calendar.getTime();
        }
        //今日
        Date todayStart = yestodayEnd;
        calendar.setTime(todayStart);
        calendar.add(Calendar.DAY_OF_MONTH, 1);
        Date todayEnd = calendar.getTime();

        //今天新增订单数
        List<Order> todayOrders = orderMapper
            .selectByCompanyWithDate(company.isCompanyType() ? null : company.getId(), todayStart,
                todayEnd);
        //今天新增用户
        long todayMember = passengerApi
            .countPassengerByCompany(company.isCompanyType() ? null : company.getId(), todayStart,
                todayEnd, settingUtils.get());
        //昨天新增用户
        long yestodayMember = passengerApi
            .countPassengerByCompany(company.isCompanyType() ? null : company.getId(),
                yestodayStart, yestodayEnd, settingUtils.get());

        //今天新增收入
        long todayOrderCount = 0;
        BigDecimal todayOrderCash = BigDecimal.ZERO;
        if (!CollectionUtils.isEmpty(todayOrders)) {
            for (Order order : todayOrders) {
                todayOrderCount += 1;
                todayOrderCash = todayOrderCash.add(order.getRealCash());
            }
        }

        map.put("todayOrderCount", todayOrderCount);
        map.put("todayOrderCash", todayOrderCash);
        map.put("todayMember", todayMember);
        //昨天新增订单数
        List<Order> yestodayOrders = orderMapper
            .selectByCompanyWithDate(company.isCompanyType() ? null : company.getId(),
                yestodayStart, yestodayEnd);

        //昨天新增收入
        long yestodayOrderCount = 0;
        BigDecimal yestodayOrderCash = BigDecimal.ZERO;
        if (!CollectionUtils.isEmpty(yestodayOrders)) {
            for (Order order : yestodayOrders) {
                yestodayOrderCount += 1;
                yestodayOrderCash = yestodayOrderCash.add(order.getRealCash());
            }
        }

        map.put("yestodayOrderCount", yestodayOrderCount);
        map.put("yestodayOrderCash", yestodayOrderCash);
        map.put("yestodayMember", yestodayMember);

        //一周新增用户
        List<Long> memberCountList = new ArrayList<Long>();
        List<String> dateList = new ArrayList<String>();
        for (int i = 0; i < 7; i++) {

            Calendar now = Calendar.getInstance();
            now.setTime(new Date());
            now.set(Calendar.HOUR_OF_DAY, setting.getWorkBegin());
            now.set(Calendar.MINUTE, 0);
            now.set(Calendar.SECOND, 0);
            now.add(Calendar.DAY_OF_MONTH, -i);
            Date start = now.getTime();
            String fmt = "MM-dd";
            SimpleDateFormat sdf = new SimpleDateFormat(fmt);
            String dateStr = sdf.format(start);

            dateList.add(dateStr);

            now.add(Calendar.DAY_OF_MONTH, 1);
            Date end = now.getTime();

            Long weekMemberCounts = passengerApi
                .countPassengerByCompany(company.isCompanyType() ? null : company.getId(), start,
                    end, settingUtils.get());

            memberCountList.add(weekMemberCounts);

        }

        map.put("memberCountList", memberCountList);
        map.put("dateList", dateList);
        //一周新增订单
        List<Long> orderCountList = new ArrayList<Long>();
        List<Long> orderCancelCountList = new ArrayList<Long>();
        List<BigDecimal> orderCashList = new ArrayList<BigDecimal>();
        for (int i = 0; i < 7; i++) {

            Calendar now = Calendar.getInstance();
            now.setTime(new Date());
            //今天开始时间，如果是结束时间为23:59:59
            now.set(Calendar.HOUR_OF_DAY, setting.getWorkBegin());
            now.set(Calendar.MINUTE, 0);
            now.set(Calendar.SECOND, 0);

            now.add(Calendar.DAY_OF_MONTH, -i);
            Date start = now.getTime();
            now.add(Calendar.DAY_OF_MONTH, 1);
            Date end = now.getTime();

            List<Order> weekOrders = orderMapper
                .selectByCompanyWithDate(company.isCompanyType() ? null : company.getId(), start,
                    end);

            long orderCount = 0;
            long orderCancelCount = 0;
            BigDecimal orderCash = BigDecimal.ZERO;
            if (!CollectionUtils.isEmpty(weekOrders)) {
                for (Order order : weekOrders) {
                    orderCount += 1;
                    orderCash = orderCash.add(order.getRealCash());
                    if (order.getStatus().equals(Order.ORDER_STATUS_CANCELED)) {
                        orderCancelCount += 1;
                    }
                }
            }

            orderCountList.add(orderCount);
            orderCancelCountList.add(orderCancelCount);
            orderCashList.add(orderCash);
        }

        map.put("orderCountList", orderCountList);
        map.put("orderCancelCountList", orderCancelCountList);
        map.put("orderCashList", orderCashList);

        if (!company.isCompanyType()) {
            map.put("newOrderCount", orderMapper
                .countByCompanyWithStatus(company.getId(), Order.ORDER_STATUS_NEW, null));
        } else {
            map.put("newOrderCount",
                orderMapper.countByCompanyWithStatus(null, Order.ORDER_STATUS_NEW, null));
        }

        Subject currentUser = SecurityUtils.getSubject();
        Principal principal = (Principal) currentUser.getPrincipal();
        if (null != principal) {
            //异常订单
            Calendar warmCalendar = Calendar.getInstance();
            warmCalendar.set(Calendar.HOUR_OF_DAY, 0);
            warmCalendar.set(Calendar.MINUTE, 0);
            warmCalendar.set(Calendar.SECOND, 0);
            warmCalendar.add(Calendar.DAY_OF_MONTH, -1);
            map.put("yesterdayWarms", orderMapper.countWarmByCompanyWithDate(
                principal.isCompanyType() ? null : principal.getCompanyId(),
                warmCalendar.getTime()));
            warmCalendar.add(Calendar.DAY_OF_MONTH, -6);
            map.put("lastWeekWarms", orderMapper.countWarmByCompanyWithDate(
                principal.isCompanyType() ? null : principal.getCompanyId(),
                warmCalendar.getTime()));
            warmCalendar.add(Calendar.DAY_OF_MONTH, 7);
            warmCalendar.add(Calendar.MONTH, -1);
            map.put("lastMonthWarms", orderMapper.countWarmByCompanyWithDate(
                principal.isCompanyType() ? null : principal.getCompanyId(),
                warmCalendar.getTime()));
        }

        return map;
    }


    @Override
    public List<Driver> getWorkingDrivers(Admin admin) {

        Company company = companyMapper.selectByPrimaryKey(admin.getCompanyId());

        return driverMapper.selectByWorking(company.isCompanyType() ? null : company.getId());
    }


    @Override
    public List<Order> allNewOrder(Admin admin) {

        Company company = companyMapper.selectByPrimaryKey(admin.getCompanyId());

        if (!company.isCompanyType()) {
            return orderMapper
                .selectByCompanyWithStatus(company.getId(), Order.ORDER_STATUS_NEW, null);
        } else {
            return orderMapper.selectByCompanyWithStatus(null, Order.ORDER_STATUS_NEW, null);
        }

    }


    @Transactional(rollbackFor = Exception.class)
    public void bossCancel(Admin admin, Order order, String content) {

        Integer oldOrderStatus = order.getStatus();

        //更新订单为销单
        order.setStatus(Order.ORDER_STATUS_CANCELED);
        order.setDriverId(null);
        order.setDriverName(null);
        order.setDriverRealName(null);
        order.setDriverPhone(null);
        orderMapper.updateByPrimaryKey(order);

        //添加一条订单状态
        OrderStatus os = new OrderStatus();
        os.setOrderId(order.getId());
        os.setStatusType(StatusType.xiaodan);
        os.setContent("【" + admin.getUsername() + "】取消了该订单");
        os.setMemo(content);
        os.setHappened(new Date());
        orderStatusMapper.insertRecord(os);

        //销单事件
        OrderCancelEvent cancelEvent = new OrderCancelEvent(order, null, null, oldOrderStatus,
            "admin");
        applicationEventMulticaster.multicastEvent(cancelEvent);

        chartYearService.addDayRecord(order);

    }


    @Transactional(rollbackFor = Exception.class)
    public void bossYupaidan(Admin admin, Driver driver, Order order) {

        order.setDriverId(driver.getId());
        order.setDriverName(driver.getName());
        order.setDriverRealName(driver.getRealname());
        order.setDriverPhone(driver.getPhone());
        if (driver.getStatus().equals(Driver.DRIVER_ONLINE)) {
            order.setStatus(Order.ORDER_STATUS_YIPAIDAN);
        } else {
            order.setStatus(Order.ORDER_STATUS_YUPAIDAN);
        }
        orderMapper.updateByPrimaryKey(order);

        //设置司机为接单
        if (driver.getStatus().equals(Driver.DRIVER_ONLINE)) {
            driverMapper.updateStatusAndJobStatusByPrimaryKey(Driver.DRIVER_APPLY_ORDER,
                Driver.DRIVER_JOBSTATUS_DAIJIA, driver.getId());
        }

        //扣费
        Setting setting = settingUtils.get();
        //
        if (setting.getInfoFee() != 0) {
            if (driver.getStatus().equals(Driver.DRIVER_ONLINE) && null != setting.getInfoFeeType()
                && setting.getInfoFeeType().equals(InfoFeeType.paidan)) {
                //更新费用
                driverMapper.updateVirtualByPrimaryKey(
                    driver.getVirtual().subtract(new BigDecimal(setting.getInfoFee())),
                    driver.getId());
                //扣费记录
                DriverPaymentsRecord driverPaymentsRecord = new DriverPaymentsRecord();
                driverPaymentsRecord.setMoney(new BigDecimal(setting.getInfoFee()));
                driverPaymentsRecord.setAfterMoney(driver.getVirtual());
                driverPaymentsRecord.setRecordType(DriverPaymentsRecord.CONSUMEDRECORD_TYPE_XINXI);
                driverPaymentsRecord.setDriverId(driver.getId());
                driverPaymentsRecord.setDriverRealName(driver.getRealname());
                driverPaymentsRecord.setDriverUserName(driver.getUsername());
                driverPaymentsRecord.setDriverPhone(driver.getPhone());
                driverPaymentsRecord.setDriverCompanyId(driver.getCompanyId());
                driverPaymentsRecord.setOrderId(order.getId());
                driverPaymentsRecord.setOrderNumber(order.getOrderNumber());
                driverPaymentsRecord.setOrderType(DriverPaymentsRecord.ORDER_TYPE_DAIJIA);
                driverPaymentsRecord.setOrderCompanyId(order.getCompanyId());
                driverPaymentsRecord.setMemo("扣除公司所得保险费/信息费" + setting.getInfoFee() + "元。");
                driverPaymentsRecord.setOperating(DriverPaymentsRecord.OPERATING_SYS);
                driverPaymentsRecord.setRcType(DriverPaymentsRecord.DIFFERENT_NEGATIVE);
                driverPaymentsRecord.setHappend(new Date());
                driverPaymentsRecordMapper.insertRecord(driverPaymentsRecord);

                //财务记录（保险费/信息费）
                Company mainCompany = companyMapper.selectMainCompany();
                DateFormat format_f = new SimpleDateFormat("yyyyMMdd");
                FinancialRecord financialRecord = new FinancialRecord();
                StringBuilder sb_f = new StringBuilder();
                sb_f.append(OrderNumberConfig.FINANCIAL_XINXI);//保险费/信息费
                sb_f.append(OrderNumberConfig.FINANCIAL_WHO_DRIVER);//对象 司机
                sb_f.append(format_f.format(new Date()));//年月日时间
                sb_f.append(
                    OrderNumberConfig.padZero(financialRecordMapper.getRunningNumber() + 1));//流水号
                financialRecord.setCode(sb_f.toString());
                financialRecord.setCompanyId(mainCompany.getId());
                financialRecord.setCompanyName(mainCompany.getAbbreviation());
                financialRecord.setOrderCompanyId(mainCompany.getId());
                financialRecord.setOrderCompanyName(mainCompany.getAbbreviation());
                financialRecord.setMemo(
                    "订单号【<a target='_blank' href='/order/detail/" + order.getId() + "'>" + order
                        .getOrderNumber() + "</a>】保险费/信息费");
                financialRecord.setMoney(new BigDecimal(setting.getInfoFee()));
                financialRecord.setStatus(FinancialRecord.FINANCIALRECORD_OK);
                financialRecord.setWho(driver.getRealname());
                financialRecord.setOrderId(order.getId());
                financialRecord.setType(FinancialRecord.FINANCIALRECORD_TYPE_XINXI);
                financialRecordMapper.insertRecord(financialRecord);
            }
        }

        //添加一条订单状态
        OrderStatus os = new OrderStatus();
        os.setOrderId(order.getId());
        os.setStatusType(StatusType.paidan);
        os.setContent("【" + admin.getUsername() + "】派单给服务人员：" + driver.getRealname());
        os.setHappened(new Date());
        orderStatusMapper.insertRecord(os);

        //手动派单后取消自动派单
        try {
            Timer timer = ThreadControl.TaskMaps.get("task_" + order.getId());
            if (null != timer) {
                timer.cancel();
                ThreadControl.TaskMaps.remove("task_" + order.getId());
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        //自动收回
        if (setting.getRevokeTime() != 0) {
            try {
                //订单自动收回定时器
                Timer timer = new Timer();
                OrderRevokeTimerTask orderRevokeTimerTask = new OrderRevokeTimerTask(order.getId(),
                    "daijia", applicationEventMulticaster);
                Integer howLong = setting.getRevokeTime();
                timer.schedule(orderRevokeTimerTask, howLong * 1000);
            } catch (Exception e1) {
                e1.printStackTrace();
            }
        }

    }

    @Transactional(rollbackFor = Exception.class)
    public List<Order> createOrder(Admin admin, Company company, Order order, Integer driverNum) {

        //根据客户电话查询客户
        Result<Passenger> result_p = passengerApi
            .findOnePassengerByPhone(order.getClientPhone(), settingUtils.get());
        Passenger passenger = result_p.getResult();
        if (null != passenger) {
            //老客户 更新位置
            passengerApi.updatePassengerFromPlace(passenger.getId(), order.getFromPlace(),
                order.getClientLongitude(), order.getClientLatitude(), settingUtils.get());
        } else {
            //新客户
            passenger = new Passenger();
            passenger.setName(order.getClientName());
            passenger.setPhone(order.getClientPhone());
            passenger.setChannel_name(Passenger.PASSENGER_CHANNEL_PHONE);
            passenger.setType(Passenger.TYPE_PASSENGER);
            passenger.setAllowOverdraw(false);
            passenger.setLongitude(order.getClientLongitude());
            passenger.setLatitude(order.getClientLatitude());
            passenger.setCompanyId(company.getId());
            passenger.setCompanyName(company.getAbbreviation());
            Result<Passenger> result = passengerApi.createPersonal(passenger, settingUtils.get());
            if (result.isSuccess()) {
                passenger = result.getResult();
            }

        }

        DateFormat format = new SimpleDateFormat("yyyyMMdd");

        order.setClientId(passenger.getId());

        List<Order> newOrders = new ArrayList<Order>();

        //生成订单号
        StringBuilder sb = new StringBuilder();

        sb.append(OrderNumberConfig.BOSS);//客户端
        if (null != passenger && passenger.getType().equals(Passenger.TYPE_ENTERPRISE)) {
            sb.append(OrderNumberConfig.COMPANY);//企业用户
        } else {
            sb.append(OrderNumberConfig.CUSTOMER);//普通用户
        }
        sb.append(format.format(new Date()));//年月日时间
        String sbStr = sb.toString();
        long number = orderMapper.getRunningNumber();

        if (passenger.isInBlackList()) {
            if (StringUtils.isBlank(order.getMemo())) {
                order.setMemo("黑名单客户");
            } else {
                order.setMemo(order.getMemo() + ";" + "黑名单客户");
            }
        }

        if (driverNum > 1) {
            OrderGroup orderGroup = new OrderGroup();
            orderGroupMapper.insertRecord(orderGroup);
            order.setOrderGroupId(orderGroup.getId());
            if (StringUtils.isBlank(order.getMemo())) {
                order.setMemo("客户同时预约" + driverNum + "人");
            } else {
                order.setMemo(order.getMemo() + ";" + "客户同时预约" + driverNum + "人");
            }
        }

        for (int i = 1; i <= driverNum; i++) {
            Order dborder = new Order();
            BeanUtils.copyProperties(order, dborder);
            dborder.setStatus(0);
            dborder.setOrderType(Order.ORDER_TYPE_PHONE);
            if (passenger.getType().equals(Passenger.TYPE_PASSENGER)) {
                dborder.setMemberType(Order.ORDER_MEMBER_TYPE_PASSENGER);
            } else if (passenger.getType().equals(Passenger.TYPE_ENTERPRISE)) {
                dborder.setMemberType(Order.ORDER_MEMBER_TYPE_ENTERPRISE);
            }
            dborder.setCompanyId(company.getId());

            number += 1;
            dborder.setOrderNumber(sbStr + OrderNumberConfig.padZero(number));

            orderMapper.insertRecord(dborder);
            newOrders.add(dborder);

            //添加一条订单状态
            OrderStatus os = new OrderStatus();
            os.setOrderId(dborder.getId());
            os.setStatusType(StatusType.neworder);
            os.setContent("老板端【" + admin.getUsername() + "】下单");
            os.setHappened(new Date());
            orderStatusMapper.insertRecord(os);

        }

        return newOrders;

    }


}